Skip to main content

使用原生SDK上报JS异常

Bugly 支持跨平台开发框架通过调用 Native 层 SDK 来上报 JS 层数据。以下是 React Native 通过桥接方式调用 Native 层 SDK 上报JS异常的示例。

React Native 提供了桥接机制来调用 Native 层函数。下面将展示如何在 React Native 中使用 iOS 和 Android 的 SDK 来上报 JS 异常。Bugly 基于 React Native 官方文档实现了相应的桥接功能。Android原生模块桥接文档IOS原生模块桥接文档

Android

首先在app/com.app-name里创建kotlin文件,其中 AppPackage,AndroidBridge,OnError为新增的文件。

文件列表

在OnError中调用 Android SDK 上报错误数据

// OnError.kt
package com.awesomeproject;
import android.util.Log;
public class OnError {
public void sendMsg(String errMsg) {
// 使用 Android SDK 上报错误数据
Map<String, String> extraInfo = new HashMap<>();
String[] components = errMsg.split("\n");
String msg = components[0].replace("Error: ", "");
String[] secondPart = Arrays.copyOfRange(components, 1, components.length);
String stack = String.join("\n", secondPart);
Bugly.postException(8, "test_error", msg , stack, extraInfo);
}
}

在 AndroidBridge中声明 AndroidBridge,并调用OnError类来上报错误信息。

// AndroidBridge.kt
package com.awesomeproject;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

public class AndroidBridge extends ReactContextBaseJavaModule{
AndroidBridge(ReactApplicationContext context) {
super(context);
}
private OnError onError = new OnError();
@NonNull
@Override
public String getName() {
return "AndroidBridge";
}
@ReactMethod
public void sendJSError (String errMsg) {
onError.sendMsg(errMsg);
}
}

然后向React Native中注册AndroidBridge

// AppPackage.kt
package com.awesomeproject;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AppPackage implements ReactPackage{
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext context) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules (ReactApplicationContext context) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new AndroidBridge(context));
return modules;
}
}

最后在MainApplication里添加AppPackage。

// MainApplication.kt
package com.awesomeproject
import android.app.Application
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactHost
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
import com.facebook.react.ReactNativeHost
import com.facebook.react.ReactPackage
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
import com.facebook.react.defaults.DefaultReactNativeHost

class MainApplication : Application(), ReactApplication {

override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
add(AppPackage())
}

override fun getJSMainModuleName(): String = "index"

override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG

override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
}

override val reactHost: ReactHost
get() = getDefaultReactHost(applicationContext, reactNativeHost)

override fun onCreate() {
super.onCreate()
loadReactNative(this)
}
}

在JS层调用Android SDK 来上报错误数据

import { NativeModules } from 'react-native';
const { AndroidBridge } = NativeModules
ErrorUtils.setGlobalHandler((error, isFatal) => {
AndroidBridge.sendJSError(error.stack || error);
});

上报的错误数据将在【错误】栏目中展示 安卓上报js异常

IOS

在项目根目录下创建OnError.swift,IOSBridge.swift和IOSBridge.m文件。

// OnError.swift
class OnError {
func tran2BuglyError(errMsg: String) -> (category: UInt, name:String, reason: String, callStack: Array<String>) {
let components = errMsg.components(separatedBy: "\n")
let firstPart = components[0].replacingOccurrences(of: "Error: ", with: "")
let secondPart = Array(components.dropFirst())
return (5, "JS Error", firstPart, secondPart)
}

public func sendMsg(errMsg: String) -> Void {
let BuglyError = tran2BuglyError(errMsg: errMsg)
// 调用 Bugly IOS 上报错误
BuglyCrashMonitorPlugin.reportException(withCategory: BuglyError.category, name: BuglyError.name, reason: BuglyError.reason, callStack: BuglyError.callStack, extraInfo: [:], terminateApp: false)
}
}

// IOSBridge.swift
@objc(IOSBridge)
class IOSBridge: NSObject {
@objc(sendJSError:)
func sendJSError(errMsg: String) -> Void {
let onError = OnError()
onError.sendMsg(errMsg: errMsg)
}
}

// IOSBridge.m
#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE(IOSBridge, NSObject)

RCT_EXTERN_METHOD(sendJSError:(NSString *)errMsg)

@end

创建桥接文件

// AwesomeProject_Bridging_Header.h
#ifndef AwesomeProject_Bridging_Header_h
#define AwesomeProject_Bridging_Header_h
#import <React/RCTBridgeModule.h>

#endif /* AwesomeProject_Bridging_Header_h */

最后在JS层中监听错误并调用IOS与Android上报错误

import { NativeModules } from 'react-native';
const { IOSBridge } = NativeModules
ErrorUtils.setGlobalHandler((error, isFatal) => {
IOSBridge.sendJSError(error.stack || error);
});

上报的错误数据将在【错误】栏目中展示 ios上报js异常